// msgchain.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <stdlib.h>
#include <memory.h>
#include <exception>
#include <char_traits.h>
#include <vector>
#include <atlstr.h>

#include <iostream>
#ifdef _UNICODE
    #define _tcout _STD wcout
#else
    #define _tcout _STD cout
#endif

#define _$ _tcout 
#define $_ _STD endl 


// stl strings
template<typename _Char>
print_buffer<_Char>& operator<<(print_buffer<_Char>& buf_, const _STD string& val_)
{
    return buf_.put(val_.c_str(), val_.length());
}

template<typename _Char>
print_buffer<_Char>& operator<<(print_buffer<_Char>& buf_, const _STD wstring& val_)
{
    return buf_.put(val_.c_str(), val_.length());
}

template<typename _Char>
class string_print : public print_buffer<_Char>
{
public:
    typedef typename ChTraits<_Char>::pointer pointer;
    typedef typename ChTraits<_Char>::const_pointer const_pointer;
    typedef _STD basic_string<_Char>    StringType;
private:
    string_print<_Char>();
    string_print<_Char>(const string_print<_Char>&);
    string_print<_Char>& operator=(const string_print<_Char>&);

protected:
    StringType&     _str;

    size_t   advance(size_t length_)
    {
        if (length_ != no_value)
        {
            if (_str.size() + length_ >= _str.capacity())
                ::Inl::_Xran();
            _str.append(_str.data() + _str.size(), length_);
        }
        return size();
    }
public:
    string_print<_Char>(StringType& str_)
        : _str(str_)
    {
        _str.reserve(128);
    }

    size_t  size() const
    {
        return _str.size();
    }

    const_pointer   data(size_t at_) const
    {
        return &_str.at(at_);
    }

    pointer get(size_t size_)
    {
        if (_str.size() + size_ >= _str.capacity())
            _str.reserve(_str.size()+size_);
        return const_cast<pointer>(_str.data()) + _str.size();
    }
    size_t append(const_pointer data_, size_t length_)
    {
        if (length_ == no_value)
            length_ = ChTraits<_Char>::length(data_);
        _str.insert(_str.size(), data_, length_);
        return length_;
    }
    void  reset()
    {
        _str.clear();
        _str.reserve(128);
    }
};

// atl strings
template<typename _Char>
print_buffer<_Char>& operator<<(print_buffer<_Char>& buf_, const ATL::CStringA& val_)
{
    return buf_.put(val_.GetString(), val_.GetLength());
}

template<typename _Char>
print_buffer<_Char>& operator<<(print_buffer<_Char>& buf_, const ATL::CStringW& val_)
{
    return buf_.put(val_.GetString(), val_.GetLength());
}

template <typename _Char = char>
struct  atl_string
{
    typedef ATL::CAtlStringA    type;
};
template <>
struct  atl_string<wchar_t>
{
    typedef ATL::CAtlStringW    type;
};

template<typename _Char>
class atl_string_print : public print_buffer<_Char>
{
public:
    typedef typename ChTraits<_Char>::pointer pointer;
    typedef typename ChTraits<_Char>::const_pointer const_pointer;
    typedef typename atl_string<_Char>::type    StringType;
private:
    atl_string_print<_Char>();
    atl_string_print<_Char>(const atl_string_print<_Char>&);
    atl_string_print<_Char>& operator=(const atl_string_print<_Char>&);

protected:
    StringType&     _str;

    void internal_grow(size_t size_)
    {
        _str.GetBuffer((int)size_);
        _str.ReleaseBufferSetLength((int)size_);
    }

    size_t   advance(size_t length_)
    {
        if (length_ != no_value)
        {
            size_t newSize = (size_t)_str.GetLength() + length_;
            if (newSize >= (size_t)_str.GetAllocLength())
                ::Inl::_Xran();
            internal_grow(newSize);
        }
        return size();
    }
public:
    atl_string_print<_Char>(StringType& str_)
        : _str(str_)
    {
        _str.Preallocate(128);
    }

    size_t  size() const
    {
        return _str.GetLength();
    }

    const_pointer   data(size_t at_) const
    {
        if (at_ >= (size_t)_str.GetLength())
            ::Inl::_Xran();
        return _str.GetString() + at_;
    }

    pointer get(size_t size_)
    {
        size_t newSize = (size_t)_str.GetLength() + size_;
        if (newSize >= (size_t)_str.GetAllocLength())
            internal_grow(newSize);
        return const_cast<pointer>(_str.GetString()) + _str.GetLength();
    }
    size_t append(const_pointer data_, size_t length_)
    {
        if (length_ == no_value)
            length_ = ChTraits<_Char>::length(data_);
        if (data_ != _str.GetString()+size())
            _str.Append(data_, (int)length_);
        else
            internal_grow((size_t)_str.GetLength()+length_);
        return length_;
    }
    void  reset()
    {
        _str.Empty();
        _str.Preallocate(128);
    }
};


template<typename StringType>
struct  _string;

template <>
struct  _string<_STD string >
{
    typedef char                    char_t;
    typedef ChTraits<char_t>        traits;
    typedef string_print<char_t>    printer;
    typedef _STD string             type;
};

template <>
struct  _string<_STD wstring >
{
    typedef wchar_t                 char_t;
    typedef ChTraits<char_t>        traits;
    typedef string_print<char_t>    printer;
    typedef _STD wstring            type;
};

template <>
struct  _string<ATL::CAtlStringA>
{
    typedef char                    char_t;
    typedef ChTraits<char_t>        traits;
    typedef atl_string_print<char_t>    printer;
    typedef ATL::CAtlStringA        type;
};

template <>
struct  _string<ATL::CAtlStringW>
{
    typedef wchar_t                 char_t;
    typedef ChTraits<char_t>        traits;
    typedef atl_string_print<char_t>    printer;
    typedef ATL::CAtlStringW        type;
};

template <typename StringType>
print_buffer<typename _string<StringType>::char_t>* createBuffer(StringType& str_);

template <>
static inline print_buffer<char>* createBuffer(_STD string& str_)
{
    return new _string<_STD string>::printer(str_);
}
template <>
static inline print_buffer<wchar_t>* createBuffer(_STD wstring& str_)
{
    return new _string<_STD wstring>::printer(str_);
}

template <>
static inline print_buffer<char>* createBuffer(ATL::CAtlStringA& str_)
{
    return new _string<ATL::CAtlStringA>::printer(str_);
}

template <>
static inline print_buffer<wchar_t>* createBuffer(ATL::CAtlStringW& str_)
{
    return new _string<ATL::CAtlStringW>::printer(str_);
}


template <typename StringType>
class   formatter
{
public:
    typedef _string<StringType>     _Str;
    
protected:
    typename _Str::type             _data;
};

template <typename _CharT, class _Alloc = _STD allocator<_CharT>, const size_t _InitialSize = 128>
class   format_buffer : public print_buffer<_CharT>
{
public:
    typedef typename TypeConv<_CharT>::_Traits _Traits;
    typedef typename _Traits::pointer pointer;
    typedef typename _Traits::const_pointer const_pointer;
    typedef typename TypeConv<_CharT>::print_buffer _Base;

    typedef format_buffer<_CharT, _Alloc, _InitialSize>  _Myt;
protected:

    typedef typename _Alloc::template rebind<_CharT>::other _Alty;

    static const size_t     _default_limit = _InitialSize;

    _CharT      _default[_default_limit];
    _Alty       _al;
    size_t      _limit;
    size_t      _count;
    pointer     _data;


    void realloc(size_t  size_)
    {
        if (size_ < _limit)
            return;

        size_t newLimit = _default_limit * (1 + (size_ / _default_limit));
        pointer newData = _al.allocate(newLimit);
        if (!newData)
            ::Inl:: _Xalloc();
        _Traits::copy(newData, newLimit, _data, _count);
        _Traits::fill(newData+_count, newLimit-_count, 0);
        if (_data != _default)
            _al.deallocate(_data, _limit);
        _data = newData;
        _limit = newLimit;
    }

public:
    _Myt()
        : _limit(_default_limit)
        , _count(0)
        , _data(_default)
    {
        _Traits::fill(_data, _limit, 0);
    }

    ~format_buffer()
    {
        if (_data != _default)
            _al.deallocate(_data, _limit);
    }

    operator const_pointer() const
    {
        return _data;
    }

    // print_buffer::size()
    size_t  size() const 
    {
        return _count;
    }

    const_pointer   data(size_t at_) const
    {
        if (at_ >= _limit)
            ::Inl::_Xran();
        return _data + at_;
    }

    // print_buffer::get()
    pointer get(size_t length_)
    {
        if (length_ == no_value)
            ::Inl::_Xinvarg();
        realloc(_count + length_);
        return _data+_count;
    }

    // print_buffer::append()
    size_t append(const_pointer  data_, size_t length_)
    {
        if (length_ == no_value)
            length_ = _Traits::length(data_);
        if (0 != _Traits::copy(get(length_+1), length_, data_, length_))
            ::Inl::_Xinvarg();
        _count += length_;
        _data[_count] = _CharT(0);
        return length_;
    }

    // print_buffer::reset()
    void    reset()
    {
        if (_data != _default)
        {
            _al.deallocate(_data, _count);
        }
        _data = _default;
        _limit = _default_limit;
        _count = 0;
        _Traits::fill(_data, _limit, 0);
    }

    // print_buffer::advance()
protected:
    size_t advance(size_t length_)
    {
        if (length_ != no_value)
        {
            if (_count + length_ >= _limit)
                ::Inl:: _Xran();
            _count += length_;
        }
        _data[_count] = _CharT(0);
        return _count;
    }

public:
    void appendNull()
    {
        static _CharT   _null[] = {'(', 'n', 'u', 'l', 'l', ')', 0};
        append(_null, 6);
    }

};

struct  chunk 
{
    typedef _STD pair<size_t, size_t>   _Pair;
    size_t  _start;
    size_t  _length;

    __forceinline chunk()
        : _start(0)
        , _length(0)
    {}

    __forceinline chunk(size_t start_, size_t length_)
        : _start(start_)
        , _length(length_)
    {}

    __forceinline chunk(const chunk& rh_)
        : _start(rh_._start)
        , _length(rh_._length)
    {}


    __forceinline chunk(const _Pair& rh_)
        : _start(rh_.first)
        , _length(rh_.second)
    {}


    __forceinline chunk&  operator=(const chunk& rh_)
    {
        _start  = rh_._start;
        _length = rh_._length;
        return *this;
    }

    __forceinline chunk&  operator=(const _Pair& rh_)
    {
        _start  = rh_.first;
        _length = rh_.second;
        return *this;
    }
    __forceinline void reset()
    {
        _start = _length = 0;
    }
    operator const _Pair& () const
    {
        return *(const _Pair*)this;
    }

};

template<typename _CharT >
class   Fmt 
{
public:
    typedef ChTraits<_CharT>    _Traits;
    typedef typename _Traits::pointer pointer;
    typedef typename _Traits::const_pointer const_pointer;
    typedef Fmt<_CharT>  _Myt;
    typedef format_buffer<_CharT>   _Fbuf;
protected:

    static const size_t default_limit = 8;
    class   format_entry
    {
    public:
        chunk   _format;
        chunk   _entry;
        size_t  _val_index;

        format_entry()
            : _val_index(no_value)
        {}

        void    reset()
        {
            _format.reset();
            _entry.reset();
            _val_index = no_value;
        }
    };

    format_entry    _default[default_limit];
    format_entry*   _data;
    size_t          _count;
    size_t          _limit;

    
    format_entry& allocate()
    {
        if (_count >= _limit)
        {
            format_entry* newData = new format_entry[_limit*2];
            for(size_t i = 0; i < _count; ++i)
            {
                newData[i] = _data[i];
            }
            if (_data != _default)
            {
                delete [] _data;
            }
            _data = newData;
            _limit *= 2;
        }

        return _data[_count++];
    }
    //static const_pointer    nil()
    //{
    //    static  const _CharT    _nil []={0};
    //    return _nil;
    //}

    _Fbuf   _buf;
    _STD    vector<chunk> _chunks;

    _Myt& parse(const_pointer format_)
    {
        reset();
        _buf.append(format_, no_value);
        if (!_buf.empty()) 
        {
            const_pointer start = format_;
            while(*start)
            {
                format_entry& entry(allocate());
                entry._format._start = start - format_;
                const_pointer ptr = skip_to(start, '{');
                size_t length =  ptr - start;
                if (*ptr == '{')
                {
                    ++ptr;
                    if (*ptr == '{')
                    {
                        ++ptr;
                        ++length;
                    }
                    else
                    {
                        const_pointer   estart = ptr;
                        ptr = skip_to(ptr, '}');
                        if (*ptr == '}') 
                        {
                            size_t index = val_index(estart, ptr - estart);
                            if (index != no_value)
                            {
                                entry._entry._start = estart - format_;
                                entry._entry._length = ptr - estart;
                                entry._val_index = index;
                                ++ptr;
                            }
                            else  
                            {
                                ptr = skip_to(ptr, '{');
                                length = ptr - start;
                            }
                        }
                        else
                            length = ptr - start;
                    }
                }
                entry._format._length = length;
                start = ptr;
            }
        }
#ifdef _DEBUG
        //dump(format_);
#endif
        return *this;
    }

#ifdef _DEBUG
    void dump(const_pointer format_)
    {
        _$ << format_ << $_;

        _$ << '[';
        for(size_t i = 0; i < _count; ++i)
        {
            const format_entry& entry(_data[i]);
            for(size_t e = 0; e < entry._format._length; ++e) 
            {
                _CharT c = format_[entry._format._start + e];
                _$ << c ;
            }
            _$ << ',';
            if (entry._val_index != no_value)
            {
                _$ << '{' << entry._val_index << '}';
            }
            _$ << '|';
        }
        _$ << ']' << $_;
        _$ << "# of entries = " << _count << $_;
    }
#endif

    void    reset()
    {
        _chunks.clear();
        _buf.reset();
        if (_data != _default)
        {
            delete _data;
            _data = _default;
            _limit = default_limit;
        }
        for(size_t i = 0; i < _limit; ++i)
            _data[i].reset();
        _count = 0;
    }
    static inline const_pointer    skip_to(const_pointer ptr_, _CharT char_)
    {
        while(*ptr_ && *ptr_ != char_)
            ++ptr_;
        return ptr_;
    }

    static size_t val_index(const_pointer data_, size_t length_ )
    {
        bool ok = false;
        size_t result = 0;
        for(size_t i = 0; i < length_; ++i)
        {
            _CharT c = data_[i]; 
            if (c >= '0' && c <= '9')
            {
                result *= 10;
                result += c - '0';
                ok = true;
            }
            else
                return no_value;
        }
        return ok?result:no_value;
    }

public:
    Fmt()
        : _count(0)
        , _data(_default)
        , _limit(default_limit)
    {}

    Fmt(const_pointer format_)
        : _count(0)
        , _data(_default)
        , _limit(default_limit)
    {
        parse(format_);
    }

    ~Fmt()
    {
        reset();
    }

    template<typename T>
    _Myt& operator, (const T& data_)
    {
        size_t save_start = _buf.size();
        _buf << data_;
        _chunks.push_back(chunk(save_start, _buf.size() - save_start));
        return *this;
    }

    _Myt& operator() (const_pointer format_)
    {
        return parse(format_);
    }

    _Fbuf&  flush(_Fbuf& fb_) const
    {
        for(size_t i = 0; i < _count; ++i)
        {
            const format_entry& entry(_data[i]);
            fb_.append_range(_buf.range(entry._format._start, entry._format._length));
            if (entry._val_index != no_value)
            {
                if (entry._val_index < _chunks.size())
                {
                    const chunk& ch = _chunks[entry._val_index];
                    fb_.append_range(_buf.range(ch._start, ch._length));
                }
                else
                    fb_.appendNull();
            }
        }
        return fb_;
    }
};

template<typename T>
class chain
{
public:
    typedef chain<T>    _Myt;

private:
    chain();
    chain(const _Myt&);
    chain&  operator=(const _Myt&);

protected:
    mutable _Myt*   _next;
    mutable _Myt**  _tail;
    T               _data;

    void    attach(const _Myt& t) const
    {
        _ASSERT(&t != this);
        _ASSERT(t._next == NULL);
        _ASSERT(t._tail == &t._next);
        *_tail = const_cast<_Myt*>(&t);
        _tail = const_cast<_Myt**>(&t._next);
    }

    _Myt*    reset()
    {
        _Myt* ret = _next;
        _next = NULL;
        _tail = &_next;
        return ret;
    }

    void    clear()
    {
        for(_Myt* next = _next; next != NULL; )
        {
            _Myt* tmp = next->reset();
            delete next;
            next = tmp;
        }
        reset();
    }

public:

    chain(const T& ref_)
        : _next(NULL)
        , _tail(&_next)
        , _data(ref_)
    {
    }

    ~chain()
    {
        clear();
    }

    size_t  size() const
    {
        size_t ret = 0;
        for(const _Myt* next = this; next != NULL; next = next->_next)
        {
            ++ret;
        }
        return ret;
    }

    inline  _Myt*  _nextInChain()
    {
        return _next;
    }

    inline    const _Myt*  _nextInChain() const
    {
        return _next;
    }

    operator const   T&() const
    {
        return _data;
    }
    
    operator T&()
    {
        return _data;
    }

    // Comma operator used to concatenate elements in the list
    // parameter 't' is the tail element concatenated with this head element, whose 'chain' component 
    // contains address of 'next' field of last element of the list     
    // returns head of the list
     
    inline _Myt& operator, (const T& t)
    {
        attach(*new _Myt(t));
        return *(_Myt*)this;
    }

    inline _Myt& operator, (T* t)
    {
        _ASSERT(t != NULL);
        attach(*new _Myt(t));
        return *(_Myt*)this;
    }

    template<class _Container>
    void  to_container(_Container& c_) const
    {
        for(const _Myt* next = this; next != NULL; next = next->_next)
        {
            c_.push_back(*next);
        }
        //clear();
    }
};


#define DEFAULT_MESSAGE_BUFFER_SIZE 256
enum    char_size {
    CS_CHAR = sizeof(char),
    CS_WCHAR = sizeof(wchar_t)
};

class variant
{
protected:
    const type_info& _ti;
    const void*      _data;
public:
    template<typename T>
    variant(const T& data_)
        : _ti(typeid(T))
        , _data(&data_)
    {}
    variant()
        : _ti(typeid(void))
        , _data(0)
    {}

    variant(const variant& rh_)
        : _ti(rh_._ti)
        , _data(rh_._data)
    {}

    void reset()
    {
        this->variant::variant();
    }

    variant& operator=(const variant& rh_)
    {
        this->variant::variant(rh_);
        return *this;
    }

    template <typename T>
    variant& set(const T& data_)
    {
        this->variant::variant(data_);
        return *this;
    }

    template <typename _CharT>
    format_buffer<_CharT>& format(format_buffer<_CharT>& fb_) const
    {
        //const printer<_CharT>& printer = getPrinter<_CharT>(_ti);
        //printer.print(fb_, _data);
        return fb_;
    }
};

class   variant_buffer
{
protected:
    static const size_t    _default_limit = 16;
    variant     _default[_default_limit];
    variant*    _data;
    size_t      _limit;
    size_t      _count;

    variant&    allocate()
    {
        if (_count >= _limit)
        {
            variant* newEntries = new variant[_limit*2];
            for(size_t i = 0; i < _count; ++i)
            {
                newEntries[i] = _data[i];
            }
            if (_data != _default)
            {
                delete [] _data;
            }
            _data = newEntries;
            _limit *= 2;
        }

        return _data[_count++];
    }

public:

    variant_buffer()
        : _data(_default)
        , _limit(_default_limit)
        , _count(0)
    {}
    ~variant_buffer()
    {
        reset();
    }

    void    reset()
    {
        if (_data != _default)
        {
            delete _data;
            _data = _default;
            _limit = _default_limit;
        }
        for(size_t i = 0; i < _limit; ++i)
            _data[i].reset();
        _count = 0;
    }
    size_t  size() const
    {
        return _count;
    }

    template<typename T>
    variant_buffer& operator,(const T& data_)
    {
        allocate().set(data_);
        return *this;
    }
    const variant&  operator[](size_t at_) const
    {
        return _data[at_];
    }
};


void type_encoding(const type_info& ti_)
{
    _$ << ti_.name() << " : " <<ti_.raw_name() << $_;
}
template<typename T>
void type_encoding()
{
    type_encoding(typeid(T));
    type_encoding(typeid(T*));
    type_encoding(typeid(const T*));
}


class prec_timer  
{
private:
	__int64 _start;
	__int64 _stop;

public:
	prec_timer() 
        : _start(0)
        , _stop(0)
    {
	}

    static  
	double to_double(const LARGE_INTEGER& val) throw()
    {
        return (double( val.u.HighPart) * -1. + val.u.LowPart);
	}

    static  inline
	double to_double(const __int64& val) throw()
    {
        return to_double(*(LARGE_INTEGER*)&val);
	}
    static
    double  getFreq() throw()
    {
	    LARGE_INTEGER freq;
        ::QueryPerformanceFrequency(&freq);
        return (to_double(freq));
    }

    static inline
    double  frequency() throw()
    {
        static double freq(getFreq());
        return freq;
    }

    static double duration(double start_, double stop_)
    {
		return (stop_ - start_)/frequency();
    }

    static  inline
    double  now()
    {
	    LARGE_INTEGER time;
        ::QueryPerformanceCounter((LARGE_INTEGER*)&time);
        return to_double(time);
    }

	inline void start() 
    {
        ::QueryPerformanceCounter((LARGE_INTEGER*)&_start);
        _stop = _start;
    }

	inline double stop() 
    {
        ::QueryPerformanceCounter((LARGE_INTEGER*)&_stop);
        return duration(to_double(_start), to_double(_stop));
	}

    double elapsed()
    {
        return duration(to_double(_start), now());
    }

    double restart()
    {
        double ret(elapsed());
        start();
        return (ret);
    }
};


#include <sstream>
#ifdef _DEBUG
#define MAXITER 1
#else
#define MAXITER 1000000
#endif
int _tmain(int argc, _TCHAR* argv[])
{
#if 0
    ATL::CAtlStringA s;
    PBuf(s);
    ATL::CAtlStringW ws;
    PBuf(ws);

    _STD string ss;
    PBuf(ss);
    _STD wstring wss;
    PBuf(wss);

    chunk::_Pair _Pair;
    chunk ch(chunk::_Pair(10, 12));
    chunk ch2 = ch;
    chunk ch3;
    _STD swap(ch3, ch2);
    chunk::_Pair p2(ch2);
    _$ << p2.first << " : " << p2.second << $_;
#else
   _$ << _MSC_VER << $_;
    int i = 5;
    int* pi = NULL;
    variant vi(i);
    variant vpi(pi);
    variant_buffer vb;
    vb ,vi, vpi;
    _$ << "start format_buffer" << $_;

    format_buffer<char> fbc;

    prec_timer t;
    t.start();
    for(size_t i = 0; i < MAXITER; i++)
    {
        format_buffer<wchar_t> fb;
        fb  << true
            << '|'
            << L'Z'
            << '|'
            << (unsigned char)178
            << '|'
            << (unsigned short)100
            << '|'
            << (__int64)-1
            << '|'
            << "(new text)"
            << '|'
            << L"(WIDE text)"
            << '|'
            << (__int64)-1
            << '|'
            << (size_t)-1
            << '|'
            << sqrt(3.14158f)
            << '|'
            << (void*)0x0002FFBE
            << '|'
            << &fbc
            ;
        if (i + 1 == MAXITER)
        {
            _$ << "stop" << $_;
            _$ << MAXITER << " iterations took " << t.stop() << " seconds" << $_;
            _$ << (const wchar_t*)fb << $_;
            fb.copy(fbc);
        }
    }

    _$ << (const char*)fbc << $_;

    _STD string ss;
    string_print<char> sp(ss);
    //ATL::CStringA ss;
    //atl_string_print<char> sp(ss);

    _$ << "start atl_string_print" << $_;
    t.start();
    for(size_t i = 0; i < MAXITER; i++)
    {
        sp.reset();
        sp  << true
            << '|'
            << L'Z'
            << '|'
            << (unsigned char)178
            << '|'
            << (unsigned short)100
            << '|'
            << (__int64)-1
            << '|'
            << "(new text)"
            << '|'
            << L"(WIDE text)"
            << '|'
            << (__int64)-1
            << '|'
            << (size_t)-1
            << '|'
            << sqrt(3.14158f)
            << '|'
            << (void*)0x0002FFBE
            << '|'
            << &fbc
            ;
        if (i + 1 == MAXITER)
        {
            _$ << "stop" << $_;
            _$ << MAXITER << " iterations took " << t.stop() << " seconds" << $_;
            _$ << ss.c_str() << $_;
        }
    }


    _$ << "start std::basic_ostringstream" << $_;
    t.start();
    for(size_t j = 0; j < MAXITER; j++)
    {
        _STD basic_ostringstream<wchar_t> s;
        //s.flush();
        s   << true
            << '|'
            << L'Z'
            << '|'
            << (unsigned char)178
            << '|'
            << (unsigned short)100
            << '|'
            << (__int64)-1
            << '|'
            << "(new text)"
            << '|'
            << L"(WIDE text)"
            << '|'
            << (__int64)-1
            << '|'
            << (size_t)-1
            << '|'
            << sqrt(3.14158f)
            << '|'
            << (void*)0x0002FFBE
            << '|'
            << &fbc
            ;
        if (j + 1 == MAXITER)
        {
            _$ << "stop" << $_;
            _$ << MAXITER << " iterations took " << t.stop() << " seconds" << $_;
            _$ << s.str().c_str() << $_;
        }
    }
    ATL::CStringA mama("Mama ");
    _STD wstring myla(L"MYLA");
    format_buffer<wchar_t> fb;
    fb << mama << myla << '|' << sqrt(3.14158) << " # \"ramu\" #" << pow(1.1003* 4.75e-20, 3);
    _$ << fb.data(0) << $_;
    sp.reset();
    fb.copy(string_print<char>(ss));
    _$ << ss.c_str() << $_;

    _STD basic_ostringstream<wchar_t> sb;
    sb << mama << myla << '|' << sqrt(3.14158) << " # \"ramu\" #" << pow(1.1003* 4.75e-20, 3);
    _$ << sb.str().c_str() << $_;

    _$ << (const TCHAR*)(Fmt<TCHAR>(_T("{0} {1} {2}. oh, {0}, oh, {2}")), mama , myla, L"ramu!" ).flush(format_buffer<TCHAR>()) << $_;
#endif
    return 0;
}

